﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data;
using System.Globalization;
using System.Linq;
using System.Runtime.CompilerServices;
using System.ServiceModel;
using System.ServiceModel.Activation;
using Application.Core.EntityService;
using Application.Core.ErrorHandlers;
using Domain.MainModule.Entities;
using Domain.MainModule.Repositories;
using Infrastructure.CrossCutting.Caching;
using Infrastructure.CrossCutting.Resource;

namespace Application.MainModule.ResourceManagement
{
    [ApplicationErrorHandler()]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class LanguageService : BaseService<Translations, int>, IDBResourceSerivce
    {
        private readonly IBlurbRepository _blurbRepository;
        private readonly ITranslationRepository _translationRepository;
        private readonly ICache _cache;

        private const string DefaultResourceCulture = "en";
        public LanguageService(IBlurbRepository blurbsRepository, ICache cache, ITranslationRepository translationsRepository)
            : base(translationsRepository, cache)
        {
            this._blurbRepository = blurbsRepository;
            this._translationRepository = translationsRepository;
        }
        private IEnumerable<Translations> All
        {
            get
            {
                return GetAll("AllTranslation", p => p.Blurbs);
            }
        }

        public string GetResourceByCultureAndKeyInternal(CultureInfo culture, string resourceKey)
        {
            try
            {
                var translate =
                    All.SingleOrDefault(
                        p =>
                        string.Compare(p.CultureCode, culture.Name, StringComparison.OrdinalIgnoreCase) == 0 &&
                        p.BlurbId == int.Parse(resourceKey));
                if (translate == null)
                {
                    if (culture.Name == DefaultResourceCulture)
                    {
                        throw new InvalidOperationException(resourceKey);
                    }
                    // try to get parent culture
                    culture = culture.Parent;
                    if (culture.Name.Length == 0)
                    {
                        culture = new CultureInfo(DefaultResourceCulture);
                    }
                    return this.GetResourceByCultureAndKeyInternal(culture, resourceKey);
                }
                return translate.TranslateContent;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        [MethodImpl(MethodImplOptions.Synchronized)]
        public ListDictionary GetResourcesByCulture(CultureInfo culture)
        {
            // make sure we have a default culture at least
            if (culture == null || culture.Name.Length == 0)
            {
                culture = new CultureInfo(DefaultResourceCulture);
            }
            var translations =
                All.Where(p => string.Compare(p.CultureCode, culture.Name, StringComparison.OrdinalIgnoreCase) == 0);
            var resourceDictionary = new ListDictionary();
            foreach (var translate in translations)
            {
                resourceDictionary.Add(translate.TranslateId, translate.TranslateContent);
            }
            return resourceDictionary;
        }

        [MethodImpl(MethodImplOptions.Synchronized)]
        public string GetResourceByCultureAndKey(CultureInfo culture, string resourceKey)
        {
            string resourceValue;
            // make sure we have a default culture at least
            if (culture == null || culture.Name.Length == 0)
            {
                culture = new CultureInfo(DefaultResourceCulture);
            }
            // recurse to find resource, includes fallback behavior
            return this.GetResourceByCultureAndKeyInternal(culture, resourceKey);
        }
        public void Dispose()
        {

        }
    }
}
